package com.corpgovernment.common.logging.service.impl;

import java.util.Arrays;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.slf4j.Logger;

import com.corpgovernment.common.logging.bo.LogTagConstants;
import com.corpgovernment.common.logging.service.LoggerService;
import com.corpgovernment.common.logging.service.LoggerServiceLoggerFactory;
import com.corpgovernment.common.logging.utils.LoggerUtils;
import com.ctrip.corp.obt.logging.marker.TagMarker;

/**
 * @author: pwang27
 * @Date: 2023/11/8 17:34
 * @Description:
 */
public class LoggerServiceImpl implements LoggerService {
    private Logger logger;

    public LoggerServiceImpl(Class<?> clazz) {
        this.logger = new LoggerServiceLoggerFactory().getLogger(clazz.getName());
    }

    private static ParameterizedMessageFactory factory = ParameterizedMessageFactory.INSTANCE;

    @Override
    public void info(String title, Object obj) {
        build(title, obj).info();
    }

    @Override
    public void info(String title, String messageFormat, Object... params) {
        build(title, format(messageFormat, params)).info();
    }

    @Override
    public void error(String title, Object obj) {
        build(title, obj).error();
    }

    @Override
    public void error(String title, String messageFormat, Object... params) {
        if (params == null || params.length == 0) {
            build(title, messageFormat).error();
            return;
        }
        Object lastParam = params[params.length - 1];
        if (lastParam instanceof Throwable) {
            Throwable ex = (Throwable)lastParam;
            Object[] infos = Arrays.copyOfRange(params, 0, params.length - 1);
            build(title, format(messageFormat, infos), ex).error();
            return;
        }
        build(title, format(messageFormat, params)).error();
    }

    @Override
    public void error(String title, Throwable e) {
        build(title, e).error();
    }

    @Override
    public void warn(String title, Object obj) {
        build(title, obj).warn();
    }

    @Override
    public void warn(String title, String messageFormat, Object... params) {
        build(title, format(messageFormat, params)).warn();
    }

    @Override
    public Map<String, String> getTags() {
        return LoggerUtils.getTags();
    }

    /**
     * 新增tag
     * @param key
     * @param value
     * @return
     */
    @Override
    public LoggerService withTag(String key, Object value) {
        LoggerUtils.withTag(key, value);
        return this;
    }

    /**
     * 删除tag
     * @param key
     * @return
     */
    @Override
    public LoggerService removeTags(String key) {
        LoggerUtils.removeTags(key);
        return this;
    }

    /**
     * 清除tag
     * @return
     */
    @Override
    public LoggerService clearTags() {
        LoggerUtils.clearTags();
        return this;
    }

    private TagMarker getMarkerWithTitle(String title) {
        TagMarker tagMarker = new TagMarker(this.logger.getName());
        this.withTag(LogTagConstants.TITLE, title);
        tagMarker.putTags(this.getTags());
        return tagMarker;
    }

    @Override
    public LoggerMessage build(String title, Object message, Throwable execption) {
        return new LoggerMessage(this.logger, this.getMarkerWithTitle(title), message, execption);
    }

    @Override
    public LoggerMessage build(String title, Throwable execption) {
        return new LoggerMessage(this.logger, this.getMarkerWithTitle(title), null, execption);
    }

    @Override
    public LoggerMessage build(String title, Object message) {
        return new LoggerMessage(this.logger, this.getMarkerWithTitle(title), message, null);
    }

    @Override
    public LoggerMessage build(String title) {
        return new LoggerMessage(this.logger, this.getMarkerWithTitle(title), null, null);
    }

    @Override
    public LoggerMessage build(String title, String message, Object... params) {
        String formatMsg = format(message, params);
        return new LoggerMessage(this.logger, this.getMarkerWithTitle(title), formatMsg, null);
    }

    /**
     * 格式化参数，{}替换符
     * @param format
     * @param args
     * @return
     */
    public static String format(String format, Object... args) {
        if (args == null || args.length == 0) {
            return format;
        }
        if (StringUtils.isBlank(format)) {
            return format;
        }
        try {
            return factory.newMessage(format, args).getFormattedMessage();
        } catch (Exception e) {
            return format;
        }
    }
}
